﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using APILocawebGateway;
using APILocawebGateway.VISA.QueryString;
using APILocawebGateway.VISA.Respostas;
using System.Web;
using System.Net;
using System.IO;
namespace APILocawebGateway.VISA
{
    /// <summary>
    /// Classe responsável por realizar todas as requisições do VISAVBV. Esta classe utiliza uma instancia da classe
    /// ConfiguracaoVisaVBV.
    /// </summary>
    public sealed class GerenciadorRequisicaoVISA
    {

        private ConfiguracaoVISA _configuracaoVisaVBV;
        private RespostaVISA _respostaVisa;
        /// <summary>
        /// Este método é responsável pela criação do gerenciador de requisição VISA
        /// </summary>
        /// <param name="configuracaoVisaVBV">Objeto que contém a configuração VISAVBV</param>
        /// <param name="respostaVisa">Objeto que representa o retorno obtido do envio de dados do VISAVBV</param>
        public GerenciadorRequisicaoVISA(ConfiguracaoVISA configuracaoVisaVBV, RespostaVISA respostaVisa)
        {
            this._configuracaoVisaVBV = configuracaoVisaVBV;
            this._respostaVisa = respostaVisa;
        }

        /// <summary>
        /// Este método Realiza o Reenvio e Retorna um objeto do tipo RespostaRequisicaoReenvio
        /// </summary>
        /// <returns></returns>
        public RespostaSegundaRequisicaoVISA RealizarRequisicaoReenvio()
        {
            System.Collections.Specialized.NameValueCollection queryString = new System.Collections.Specialized.NameValueCollection();
            queryString.Add("identificacao", _configuracaoVisaVBV.Identificacao);
            queryString.Add("ambiente", _configuracaoVisaVBV.Ambiente.ToString());
            queryString.Add("modulo", Modulos.VISAVBV);
            queryString.Add("operacao", "Retorno");
            queryString.Add("tid", _respostaVisa.NumeroTransacao);
            queryString.Add("URLRetornoVisa", HttpUtility.UrlEncode(_configuracaoVisaVBV.UrlRetornoVisa));
            return ObterResultadoReenvio(Utilidades.RealizarRequisicaoModoPost(queryString));

        }

        /// <summary>
        /// Este método retorna uma string que deve ser renderizada no HttpContext, se desejado
        /// o método RenderizarRequisicaoCapturaInicial pode ser usado
        /// </summary>
        /// <param name="respostaRequisicaoReenvio"></param>
        /// <returns></returns>
        public String RealizarRequisicaoCaptura(RespostaSegundaRequisicaoVISA respostaRequisicaoReenvio)
        {

            System.Collections.Specialized.NameValueCollection queryStringCaptura = new System.Collections.Specialized.NameValueCollection();



            queryStringCaptura.Add("tid", respostaRequisicaoReenvio.NumeroTransacao);
            queryStringCaptura.Add("ambiente", _configuracaoVisaVBV.Ambiente.ToString());
            queryStringCaptura.Add("modulo", Modulos.VISAVBV);
            queryStringCaptura.Add("Operacao", "Captura");
            queryStringCaptura.Add("free", respostaRequisicaoReenvio.CampoLivre);
            queryStringCaptura.Add("identificacao", _configuracaoVisaVBV.Identificacao);

            return RealizarRequisicaoCapturaVISA(Configuracao.URLCOMPONENTELOCAWEB + "?" + Utilidades.GerarQueryString(queryStringCaptura));
        }

        /// <summary>
        /// Este método pode ser utilizado para renderizar o retorno inicial
        /// </summary>
        /// <param name="resposta"></param>
        /// <param name="contexto"></param>
        public void RenderizarRequisicaoCapturaInicial(String resposta, HttpContext contexto)
        {
            contexto.Response.ClearContent();
            contexto.Response.Clear();
            contexto.Response.Write(resposta);


        }

        /// <summary>
        /// Este método obtem o resultado da captura e devolve um objeto do tipo RespostaRequisicaoCaptura
        /// </summary>
        /// <param name="fonte"></param>
        /// <returns></returns>
        /// [Obsolete("O método não está funcionando corretamente com o ambiente da locaweb")]
        public static RespostaRequisicaoCapturaVISA ObterResultadoCaptura(HttpContext contexto)
        {
            //TODO: nem todos os valores de retorno foram implementados
            RespostaRequisicaoCapturaVISA respostaRequisicaoCaptura = new RespostaRequisicaoCapturaVISA();
            respostaRequisicaoCaptura.Codigoretornotransacao = contexto.Request["lr"];
            respostaRequisicaoCaptura.Numerotransacao = contexto.Request["tid"];
            respostaRequisicaoCaptura.Ars = contexto.Request["ars"];
            respostaRequisicaoCaptura.Campolivre = contexto.Request["free"];
            return respostaRequisicaoCaptura;
        }

        /// <summary>
        /// Este método obtem o resultado do Reenvio e devolve um objeto do tipo RespostaRequisicaoReenvio preenchido
        /// </summary>
        /// <param name="fonte"></param>
        /// <returns></returns>
        private RespostaSegundaRequisicaoVISA ObterResultadoReenvio(String fonte)
        {
            RespostaSegundaRequisicaoVISA respostaRequisicaoReenvio = new RespostaSegundaRequisicaoVISA();
            respostaRequisicaoReenvio.CodigoRetornoTransacao = Utilidades.ObterValorCampoRetorno(fonte, "lr");
            respostaRequisicaoReenvio.NumeroTransacao = Utilidades.ObterValorCampoRetorno(fonte, "tid");
            respostaRequisicaoReenvio.CampoLivre = Utilidades.ObterValorCampoRetorno(fonte, "free");
            respostaRequisicaoReenvio.Ars = Utilidades.ObterValorCampoRetorno(fonte, "ars");
            respostaRequisicaoReenvio.CodigoAutorizacao = Utilidades.ObterValorCampoRetorno(fonte, "arp");
            respostaRequisicaoReenvio.NumeroOrdem = Utilidades.ObterValorCampoRetorno(fonte, "orderid");
            respostaRequisicaoReenvio.TotalTransacao = Utilidades.ObterValorCampoRetorno(fonte, "price");
            respostaRequisicaoReenvio.HashCartao = Utilidades.ObterValorCampoRetorno(fonte, "pan");
            respostaRequisicaoReenvio.CodigoBanco = Utilidades.ObterValorCampoRetorno(fonte, "bank");

            return respostaRequisicaoReenvio;
        }

        #region Métodos para renderizar o retorno

        /// <summary>
        /// Esta função deve ser executada na página que recebe o retorno do reenvio. A função renderiza
        /// os dados.
        /// </summary>
        /// <param name="contexto"></param>
        public static void RenderizarDadosDoReenvio(HttpContext contexto)
        {
            contexto.Response.Write(Utilidades.RenderizarCampoRetorno("lr", contexto.Request[SegundoRetornoQueryStringVISA.CODIGORETORNOTRANSACAO]));
            contexto.Response.Write(Utilidades.RenderizarCampoRetorno("tid", contexto.Request[SegundoRetornoQueryStringVISA.NUMEROTRANSACAO]));
            contexto.Response.Write(Utilidades.RenderizarCampoRetorno("free", contexto.Request[SegundoRetornoQueryStringVISA.CAMPOLIVRE]));
            contexto.Response.Write(Utilidades.RenderizarCampoRetorno("ars", contexto.Request[SegundoRetornoQueryStringVISA.ARS]));
            contexto.Response.Write(Utilidades.RenderizarCampoRetorno("arp", contexto.Request[SegundoRetornoQueryStringVISA.CODIGOAUTORIZACAO]));
            contexto.Response.Write(Utilidades.RenderizarCampoRetorno("orderid", contexto.Request[SegundoRetornoQueryStringVISA.NUMEROORDEM]));
            contexto.Response.Write(Utilidades.RenderizarCampoRetorno("price", contexto.Request[SegundoRetornoQueryStringVISA.TOTALTRANSACAO]));
            contexto.Response.Write(Utilidades.RenderizarCampoRetorno("pan", contexto.Request[SegundoRetornoQueryStringVISA.HASHCARTAO]));
            contexto.Response.Write(Utilidades.RenderizarCampoRetorno("bank", contexto.Request[SegundoRetornoQueryStringVISA.CODIGOBANCO]));


        }

        /// <summary>
        /// Esta função deve ser executada na página que recebe o retorno da captura. A função renderiza
        /// os dados.
        /// </summary>
        /// <param name="contexto"></param>
        [Obsolete("O método não está funcionando corretamente com o ambiente da locaweb")]
        private static void RenderizarDadosDaCaptura(HttpContext contexto)
        {
            contexto.Response.Write(Utilidades.RenderizarCampoRetorno("lr", contexto.Request[RetornoCapturaQueryStringVISA.CODIGORETORNOTRANSACAO]));
            contexto.Response.Write(Utilidades.RenderizarCampoRetorno("tid", contexto.Request[RetornoCapturaQueryStringVISA.NUMEROTRANSACAO]));
            contexto.Response.Write(Utilidades.RenderizarCampoRetorno("cap", contexto.Request[RetornoCapturaQueryStringVISA.VALORCAPTURADO]));
            contexto.Response.Write(Utilidades.RenderizarCampoRetorno("ars", contexto.Request[RetornoCapturaQueryStringVISA.ARS]));
            contexto.Response.Write(Utilidades.RenderizarCampoRetorno("free", contexto.Request[RetornoCapturaQueryStringVISA.CAMPOLIVRE]));
        }

        #endregion

        /// <summary>
        /// Este método inicia o processo de captura do visa VBV
        /// </summary>
        /// <param name="url"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        private static String RealizarRequisicaoCapturaVISA(String url)
        {
            WebRequest webRequest;
            webRequest = WebRequest.Create(url);
            Stream objStream;

            objStream = webRequest.GetResponse().GetResponseStream();
            StreamReader objReader = new StreamReader(objStream);
            String retorno = objReader.ReadToEnd();
            return retorno;


        }







    }
}
